﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using FastNetCore.Framework.Convention;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using Microsoft.Extensions.Hosting;

namespace FastNetCore.Framework.Configurations
{
    /// <summary>
    /// 框架的核心配置类，封装了默认的服务和中间件
    /// </summary>
    public static class FrameworkConfig
    {
        /// <summary>
        /// 配置默认服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddFrameworkServices(this IServiceCollection services,
            IConfiguration configuration,
            Action<FastNetCoreOptions> configure=null)
        {
    
            ConfigurationUtils.Initializer(configuration);
            
            FastNetCoreOptions options = new FastNetCoreOptions();
            configure?.Invoke(options);

            services.AddControllers(mvcOptions =>
            {
                if (!string.IsNullOrEmpty(options.Route.DefaultRouteTemplate))
                {
                    mvcOptions.Conventions.Add(new DefaultRouteConvention(options.Route.DefaultRouteTemplate));
                }
            })
            .AddNewtonsoftJson(jsonOptions=>
            {
                //应用Newtonsoft.Json的所有配置
                ApplyNewtonsoftJsonSettings(jsonOptions.SerializerSettings,options.JsonOptions);
            });

            //Swagger配置
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen(swaggerOptions =>
            {
                swaggerOptions.SwaggerDoc(options.Swagger.Version, new()
                {
                    Title = options.Swagger.Title,
                    Version = options.Swagger.Version
                });
            });

            return services;
        }

        /// <summary>
        /// 应用Newtonsoft.Json配置
        /// </summary>
        private static void ApplyNewtonsoftJsonSettings(JsonSerializerSettings settings, NewtonsoftJsonOptions jsonOptions)
        {
            //日期处理
            settings.DateFormatString = jsonOptions.DateFormatString;
            settings.DateTimeZoneHandling = jsonOptions.DateTimeZoneHandling;
            settings.DateParseHandling = jsonOptions.DateParseHandling;

            //命名策略
            settings.ContractResolver = jsonOptions.UseCamelCase
                ? new CamelCasePropertyNamesContractResolver()
                : new DefaultContractResolver();

            //空值处理
            settings.NullValueHandling = jsonOptions.IgnoreNullValues
                ? NullValueHandling.Ignore
                : NullValueHandling.Include;

            //循环引用处理
            settings.ReferenceLoopHandling = jsonOptions.IgnoreReferenceLoops
                ? ReferenceLoopHandling.Ignore
                : ReferenceLoopHandling.Error;

            //自定义转换器
            if (jsonOptions.Converters != null && jsonOptions.Converters.Count>0)
            {
                foreach (var converter in jsonOptions.Converters)
                {
                    settings.Converters.Add(converter);
                }
            }

            //其他常用配置
            settings.Formatting = jsonOptions.Formatting;
            settings.MissingMemberHandling = jsonOptions.MissingMemberHandling;
        }

        /// <summary>
        /// 配置FastNetCore框架中间件
        /// </summary>
        public static WebApplication UseFastNetCoreMiddleware(
            this WebApplication app,
            Action<FastNetCoreOptions> configure = null)
        {
            var options = new FastNetCoreOptions();
            configure?.Invoke(options);

            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            if (options.Middleware.UseHttpsRedirection)
            {
                app.UseHttpsRedirection();
            }

            if (options.Middleware.UseAuthorization)
            {
                app.UseAuthorization();
            }

            app.MapControllers();

            return app;
        }

    }


}
